home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
mpmod160.zip
/
SOURCE.ZIP
/
Z-RX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-01
|
18KB
|
508 lines
/*--------------------------------------------------------------------------*/
/* The receive part of the Zmodem protocol. */
/* */
/* (C) Copyright M. Jose, 1990 -> */
/* See MPMODEM.DOC for more details about the usage of this source in your */
/* programs. */
/* Written by Mark Jose, Oct-Nov, 1990. */
/*---------------------------------------------------------------------------*/
[...]
#include "compress.h"
/*--------------------------------------------------------------------------*/
/* Local function prototypes */
/*--------------------------------------------------------------------------*/
static int pascal ReceiveData(BYTE *,int);
/* If you don't have a seperate routine to handle the receipt of */
/* packets with CRC-16, then you must do so in order to implement */
/* compression. */
/* */
/* Some people implement Zmodem without the ability to run it in */
/* CRC-16 mode because it will always default to the safer CRC-32 */
/* mode. This is fine, but when you want to use it over quite */
/* secure lines, CRC-16 is quite adequate. */
static int pascal ReceiveData16(BYTE *, int);
static int pascal ReceiveData32(BYTE *, int);
[...]
/*
RECEIVE DATA
This module decides what type of packet routine we should call. The type
of packet was determined when we went into Z_GetHeader (in ZMISC.C) and
set the flag of RxType.
RxType Transmission process
--------------------------------------------------------------------
0 Normal Zmodem transmission using CRC-16.
1 CRC-32 binary transfer.
2 (Not used - next release)
3 CRC-32 binary transfer with compression (when needed)
4 CRC-16 binary transfer with compression (when needed)
*/
static int pascal ReceiveData(BYTE *buf, int length)
{
static int stat;
switch (RxType) {
/*
Here we have two new options, for CRC-16 and CRC-32 compressed packets.
In order to use this method, you must call the routines with CompBuff (the
compression buffer which MUST be the same size as your normal TX/RX buffer).
When the packet is received, the frame end indicator will decide whether
the packet just received is a compressed packet. If it is, then the
decompression routine is called and the result is that the data in CompBuff
is expanded into "buf" (which is the buffer passed to this routine).
If the packet is not compressed, then a quick memcpy is done to copy it
from CompBuff to "buf".
*/
case 4: /* Possibly a compressed CRC-16 packet */
Compressed = 0;
stat = ReceiveData16(CompBuff, length);
break;
case 3: /* Possibly a compressed CRC-32 packet */
Compressed = 0;
stat = ReceiveData32(CompBuff, length);
break;
default: /* Well there shouldn't be any other type! */
case 2: /* Not used */
return ZERROR;
case 1: /* CRC-32 plain binary */
return (ReceiveData32(buf, length));
case 0: /* CRC-16 plain binary */
return (ReceiveData16(buf, length));
}
/* The only stuff to get here is compressed packets! */
/*
Now, depending on the status of the "Compressed" flag, we either decompress
the data or do a straight copy.
*/
if (Compressed) {
BlockSize = DeCompress(CompBuff, buf, BlockSize);
} else {
memcpy(buf, CompBuff, BlockSize);
}
return stat;
}
/*
In some cases, you may have to create this routine by splitting it from the
original ReceiveData() routine.
*/
/*
RZ_ReceiveData16
Handles 16 bit CRC data packets
*/
static int pascal ReceiveData16(BYTE *buf, int length)
{
register int c;
static char *endpos;
static int d;
static WORD crc;
crc = BlockSize = 0;
endpos = (char *)buf + length;
while ((char *)buf <= endpos) {
if ((c = GetZDLE()) & ~0xFF) {
CRCError:
switch (c) {
/*
This bit of code determines whether the transmission was done using
compression. If any of the following frame ends were received, they
will set the "Compressed" flag which will notify the ReceiveData()
routine.
*/
case GOTCRCE_C: /* ---** Add this **--- */
case GOTCRCG_C: /* ---** Add this **--- */
case GOTCRCQ_C: /* ---** Add this **--- */
case GOTCRCW_C: /* ---** Add this **--- */
Compressed = 1; /* ---** Add this **--- */
/* Fall through to normal process of CRC */
case GOTCRCE:
case GOTCRCG:
case GOTCRCQ:
case GOTCRCW: /* CRCs */
d = c;
crc = Z_UpdateCRC( (c & 0xFF), crc);
if ((c = GetZDLE()) & ~0xFF)
goto CRCError;
crc = Z_UpdateCRC(c, crc);
if ((c = GetZDLE()) & ~0xFF)
goto CRCError;
crc = Z_UpdateCRC(c, crc);
if (crc & 0xFFFF) {
/* Report a CRC error to main routine */
return ZERROR;
}
BlockSize = length - (int ) (endpos - (char *) buf);
return d;
case GOTCAN: /* Cancel */
return ZCAN;
case ZTIMEOUT: /* Timeout */
return c;
case RCDO: /* No carrier */
return c;
default: /* What happened? */
return c;
}
}
*buf++ = (BYTE ) c;
crc = Z_UpdateCRC(c, crc);
}
return ZERROR;
}
/*
ReceiveData32
Handles 32 bit CRC data packets
*/
static int pascal ReceiveData32(BYTE *buf, int length)
{
register int c, n;
static int d;
static char *endpos;
static ULONG crc;
BlockSize = 0;
crc = 0xFFFFFFFFL;
endpos = (char *)buf + length;
while ((char *)buf <= endpos) {
if ((c = GetZDLE()) & ~0xFF) {
CRCError:
switch (c) {
/*
This bit of code determines whether the transmission was done using
compression. If any of the following frame ends were received, they
will set the "Compressed" flag which will notify the ReceiveData()
routine.
*/
case GOTCRCE_C: /* ---** Add this **--- */
case GOTCRCG_C: /* ---** Add this **--- */
case GOTCRCQ_C: /* ---** Add this **--- */
case GOTCRCW_C: /* ---** Add this **--- */
Compressed = 1; /* ---** Add this **--- */
/* Fall through to normal process of CRC */
case GOTCRCE:
case GOTCRCG:
case GOTCRCQ:
case GOTCRCW:
d = c;
c &= 0377;
crc = Z_UpdateCRC32(c, crc);
for (n = 0; n < 4; n++) {
if ((c = GetZDLE()) & ~0xFF)
goto CRCError;
crc = Z_UpdateCRC32(c, crc);
}
if (crc != 0xDEBB20E3) {
/* Report a CRC error to main routine */
return ZERROR;
}
BlockSize = length - (int) (endpos - (char *)buf);
return(d);
case GOTCAN:
return ZCAN;
case ZTIMEOUT:
return c;
case RCDO: